float Alpha = 1.0;

uniform extern texture Texture1;
uniform extern texture Texture2;

#define BLUR_SAMPLES 15
float2 BlurOffsets[BLUR_SAMPLES];
float BlurWeights[BLUR_SAMPLES];

sampler Texture1Sampler = sampler_state
{
	Texture = <Texture1>;
	MipFilter = Linear;
    MinFilter = Linear;
    MagFilter = Linear;
    AddressU  = Clamp;
    AddressV  = Clamp;
};

sampler Texture2Sampler = sampler_state
{
	Texture = <Texture2>;
	MipFilter = Linear;
    MinFilter = Linear;
    MagFilter = Linear;
    AddressU  = Clamp;
    AddressV  = Clamp;
};

struct VertexShaderInputCombine
{
    float4 Position : POSITION0;
    float4 TexCoord : TEXCOORD0;
};

struct VertexShaderOutputCombine
{
    float4 Position : POSITION0;
	float4 TexCoord : TEXCOORD0;
	
};

struct PixelShaderOutput
{
	float4 Color : COLOR0;
};

VertexShaderOutputCombine VertexShader2D(VertexShaderInputCombine input)
{
	VertexShaderOutputCombine output = (VertexShaderOutputCombine)0;
	
	output.Position = input.Position;
	output.TexCoord = input.TexCoord;

	return output;
}

PixelShaderOutput PixelShader2D(VertexShaderOutputCombine input)
{
	PixelShaderOutput output = (PixelShaderOutput)0;
	output.Color = tex2D(Texture1Sampler, input.TexCoord);
	output.Color.a *= Alpha;
	return output;
}

float4 PixelShader2DMul(VertexShaderOutputCombine input) : COLOR0
{
	float4 t1 = tex2D(Texture1Sampler, input.TexCoord);
	float4 t2 = tex2D(Texture2Sampler, input.TexCoord);
	float4 output = t1 * t2;
	output.a = t1.a;
    return output;
}

float4 PixelShader2DAdd(VertexShaderOutputCombine input) : COLOR0
{
	float4 t1 = tex2D(Texture1Sampler, input.TexCoord);
	float4 t2 = tex2D(Texture2Sampler, input.TexCoord);
	float4 output = t1 + t2;
	output.a = 1.0f;
    return output;
}

float4 PixelShaderBlur(VertexShaderOutputCombine input) : COLOR0
{
	float4 color = 0;	
	for ( int i = 0; i < BLUR_SAMPLES; i++ )
	{
		color += tex2D(Texture1Sampler, input.TexCoord + BlurOffsets[i]) * BlurWeights[i];
	}
	return color;
}

float4 SimpleBilateralBlur(VertexShaderOutputCombine input) : COLOR0
{
	float w = 0;
	float4 color = 0;
	float3 cDepth = normalize(tex2D(Texture2Sampler, input.TexCoord).xyz);
	float cZ = tex2D(Texture2Sampler, input.TexCoord).w;
	for ( int i = 0; i < BLUR_SAMPLES; i++ )
	{
		float3 depth = normalize(tex2D(Texture2Sampler, input.TexCoord + BlurOffsets[i]).xyz);
		float cZ2 = tex2D(Texture2Sampler, input.TexCoord+ BlurOffsets[i]).w;
		if ( dot(cDepth,depth) > 0.99 && abs(cZ-cZ2) < 2.0 )
		{
			color += tex2D(Texture1Sampler, input.TexCoord + BlurOffsets[i]) * BlurWeights[i];
			w += BlurWeights[i];
		}
	}
	
	color /= w;
	
	return saturate(color);
}


technique TwoDee
{
    pass Pass0
    {
        VertexShader = compile vs_3_0 VertexShader2D();
        PixelShader = compile ps_3_0 PixelShader2D();
    }
}

technique Multiply
{
    pass Pass0
    {
        VertexShader = compile vs_3_0 VertexShader2D();
        PixelShader = compile ps_3_0 PixelShader2DMul();
    }
}


technique Add
{
    pass Pass0
    {
        VertexShader = compile vs_3_0 VertexShader2D();
        PixelShader = compile ps_3_0 PixelShader2DAdd();
    }
}

technique Blur
{
    pass Pass0
    {
        VertexShader = compile vs_3_0 VertexShader2D();
        PixelShader = compile ps_3_0 PixelShaderBlur();
    }
}

technique FulBlur
{
    pass Pass0
    {
        VertexShader = compile vs_3_0 VertexShader2D();
        PixelShader = compile ps_3_0 SimpleBilateralBlur();
    }
}



